<script lang="js" setup name="XMenu">
import { ref, computed, onMounted, reactive } from "vue";
import XSubMenu from "./XSubMenu.vue";
import XMenuItem from "./XMenuItem.vue";

const emit = defineEmits(["menuclick"]);
let menuList = ref([]);
// const props = defineProps({
//     menuList: {
//         type: Array,
//         default: () => []
//     },
// });

const xMenu = ref(null);
const menuPos = reactive({ left: 0, top: 0 });
const ItemH = 32;
const fontSize = ref(14);
const showMenu = ref(false);

const show = (menu, pos) => {
    // if (bShow) {
    //     menuList.value = menu;
    //     calcMenuPos(pos);
    // }

    menuList.value = menu;
    calcMenuPos(pos);

    showMenu.value = true;
}

const calcMenuPos = (pos) => {
    const maxHeight = document.body.clientHeight;
    const maxWidth = document.body.clientWidth;
    const isMobile = window.innerWidth <= 768 || 'ontouchstart' in window;

    // console.log('calcMenuPos:', pos, maxHeight, maxWidth, isMobile);

    // 移动端优化：确保菜单不会超出屏幕边界
    if (isMobile) {
        // 移动端：添加安全边距
        const safeMargin = 10;

        // 水平位置调整
        if (pos.left + menuWidth.value > maxWidth - safeMargin) {
            menuPos.left = Math.max(safeMargin, maxWidth - menuWidth.value - safeMargin);
        } else if (pos.left < safeMargin) {
            menuPos.left = safeMargin;
        } else {
            menuPos.left = pos.left;
        }

        // 垂直位置调整
        if (pos.top + menuHeight.value > maxHeight - safeMargin) {
            menuPos.top = Math.max(safeMargin, pos.top2 - menuHeight.value - safeMargin);
        } else if (pos.top < safeMargin) {
            menuPos.top = safeMargin;
        } else {
            menuPos.top = pos.top;
        }
    } else {
        // 桌面端原有逻辑
        if (pos.left + menuWidth.value > maxWidth) {
            menuPos.left = maxWidth - menuWidth.value;
        } else {
            menuPos.left = pos.left;
        }

        if (pos.top + menuHeight.value > maxHeight) {
            menuPos.top = pos.top2 - menuHeight.value;
        } else {
            menuPos.top = pos.top;
        }
    }

    // 最终边界检查
    menuPos.left = Math.max(0, Math.min(menuPos.left, maxWidth - menuWidth.value));
    menuPos.top = Math.max(0, Math.min(menuPos.top, maxHeight - menuHeight.value));
}

const hide = () => {
    showMenu.value = false;
}

const getRect = () => {
    return xMenu.value.getBoundingClientRect();
}

const menuWidth = computed(() => {
    let w = 80;
    // props.menuList.forEach((menu) => {
    //     const menuW = getMenuWidth(menu, fontSize.value);
    //     w = menuW > w ? menuW : w;
    // });

    menuList.value.forEach((menu) => {
        const menuW = getMenuWidth(menu, fontSize.value);
        w = menuW > w ? menuW : w;
    });

    const maxW = document.body.clientWidth / 2;

    // menu sidebar-icon width: 40px
    w += 40;
    const ret = w > maxW ? maxW : w;

    return ret;
});

const menuHeight = computed(() => {
    // let h = ItemH * props.menuList.length;
    let h = ItemH * menuList.value.length;
    return h;
});

const menuStyle = computed(() => {
    return {
        width: menuWidth.value + "px",
        left: menuPos.left + "px",
        top: menuPos.top + "px",
    };
});

const getMenuWidth = (menu, fontSize) => {
    const el = document.createElement("span");
    // el.innerText = menu.text;
    const text = menu.text;
    el.innerText = text;
    el.style.fontSize = fontSize + "px";
    el.style.position = "absolute";
    document.body.appendChild(el);
    let w = el.offsetWidth + 50;

    if (menu.image) {
        // console.log("has image:", this.$i18n.locale);
        w += 100;
    }
    document.body.removeChild(el);
    return w;
}

const hasChild = (menu) => {
    return menu.subMenu && menu.subMenu.length > 0;
}

const onMenuClick = (menu) => {
    if (menu.checkable && menu.checked !== undefined) {
        menu.checked = !menu.checked;
        if (menu.checked && menu.group) {
            for (let i = 0; i < menuList.value.length; i++) {
                if (menuList.value[i].group === menu.group) {
                    if (menuList.value[i].id !== menu.id) {
                        menuList.value[i].checked = false;
                    }
                }
            }
        }
    }
    emit("menuclick", menu);

    // 延迟关闭菜单，给cornerstone工具足够的时间完成鼠标光标更新
    setTimeout(() => {
        hide();
    }, 100); // 延迟100毫秒关闭菜单
}

const transBeforeEnter = (el) => {
    // console.log('handleBeforeEnter', el);
	el.style.height = "0px";
    el.style.overflow = "hidden";
}
const transEnter = (el) => {
    // console.log('handleEnter', el);

	el.style.height = "auto";
    const h = el.offsetHeight;
	el.style.height = "0px";
	requestAnimationFrame(() => {
		el.style.height = h + "px";
		el.style.transition = ".4s";
	});
}

const transAfterEnter = (el) => {
	el.style.transition = "initial";
     el.style.overflow = null;
}

const transBeforeLeave = (el) => {
    // console.log('handleBeforeLeave', el);
	// el.style.height = el.clientHeight + "px";
    el.style.overflow = "hidden";
	el.style.transition = ".2s";
}
const transLeave = (el) => {
    // console.log('handleLeave', el);
	el.style.height = "0px";
}
const transAfterLeave = (el) => {
    // console.log('handleAfterLeave', el);
	// el.style.display = "none";
}


defineExpose({
    show,
    hide,
    getRect,
    showMenu
});

onMounted(() => {
    // xMenu.value.focus();
});
</script>

<template>
	<!-- <Teleport to="body"> -->
	<Transition
		@beforeEnter="transBeforeEnter"
		@enter="transEnter"
		@afterEnter="transAfterEnter"
		@before-leave="transBeforeLeave"
		@leave="transLeave"
	>
		<ul class="x-menu" ref="xMenu" v-show="showMenu" :style="menuStyle">
			<template v-for="(item, index) in menuList">
				<XSubMenu
					v-if="hasChild(item)"
					:key="'submenu-' + item.id"
					:menu="item"
					:index="index"
					@menuclick="onMenuClick"
				/>
				<XMenuItem
					v-else
					:key="'menuitem-' + item.id"
					:menu="item"
					@menuclick="onMenuClick"
				/>
			</template>
		</ul>
	</Transition>
	<!-- </Teleport> -->
</template>

<style lang="scss" scoped>
.x-menu {
	position: absolute;
	background-color: var(--color-theme-bg);
	color: var(--color-theme-text);
	border: 1px solid #aaa;
	z-index: 20;
	// overflow: hidden;

	/* 移动端菜单宽度自适应 */
	@media (max-width: 768px) {
		min-width: 120px;
		max-width: 80vw;
	}

	@media (max-width: 480px) {
		min-width: 100px;
		max-width: 90vw;
	}
}
</style>
